from typing import List, Type
from sqlalchemy.orm import Session
from schemas.order import CreateOrderRequest
from db import models
from sqlalchemy import and_


class Order:
    @staticmethod
    def create(db: Session, data: CreateOrderRequest) -> models.Order:
        item = models.Order(
            created_on=data.created_on,
            customer_id=data.customer_id,
            customer_phone=data.customer_phone,
            order_code=data.order_code,
            items=[i.dict() for i in data.items],
            delivery_address=data.delivery_address.dict(),
            delivery_method=data.delivery_method,
            delivery_date=data.delivery_date,
            presale=data.presale,
            presale_delivery_date=data.presale_delivery_date,
            greeting_card=data.greeting_card,
            notes=data.notes,
            subtotal=data.subtotal,
            total_price=data.total_price,
            payment_status=data.payment_status,
            shipping_status=data.shipping_status
        )
        db.add(item)
        db.commit()
        return item

    @staticmethod
    def get_all_by_customer(db: Session, customer_id: int) -> List[Type[models.Order]]:
        return db.query(models.Order).filter(and_(
            models.Order.customer_id == customer_id,
            models.Order.status != 0
        )).all()

    @staticmethod
    def count_by_payment_status(db: Session, customer_id: int, payment_status: int) -> int:
        return db.query(models.Order).filter(and_(
            models.Order.customer_id == customer_id,
            models.Order.payment_status == payment_status,
            models.Order.status == 1
        )).count()

    @staticmethod
    def count_by_shipping_status(db: Session, customer_id: int, shipping_status: int) -> int:
        return db.query(models.Order).filter(and_(
            models.Order.customer_id == customer_id,
            models.Order.shipping_status == shipping_status,
            models.Order.payment_status == 2,
            models.Order.status == 1
        )).count()
